/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.udt.generator.api.typeprocessers.persistencevaluereader;

import com.inspur.edp.caf.generator.utils.ExpressionUtils;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.generator.UdtGeneratorContext;
import lombok.var;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;

//      生成代码例子
//     public class CompanyAssDef
//      {
//          public string ID{get;set;}
//          public string Code{get;set;}
//          public string Name{get;set;}
//      }
//
//      public interface IElementCompany
//      {
//          CompanyAssDef Company{get;set;}
//      }
//
//      public class Test
//      {
//         public object GetPersistenceValue(ICefData data);
//          {
//              IElementCompany company = data as IElementCompany;
//              if(company.Company==null)
//              return null;
//              return company.Company.ID;
//          }
//      }
//
public class UdtAssPersistenceValueGenerator extends UdtGetPersistenceValueMethodGenerator {
    private UdtGeneratorContext udtGenCtx;
    private String propertyName;
    private UdtElement element;

    public UdtAssPersistenceValueGenerator(UdtGeneratorContext udtGenCtx, String propertyName, UdtElement element) {
        this.udtGenCtx = udtGenCtx;
        this.propertyName = propertyName;
        this.element = element;
    }

    private static final String tempData = "tempData";

    @Override
    protected Block buildMethodBody() {
        var block = ast.newBlock();

        block.statements().add(addTypeAsStatements());
        block.statements().add(addIfNullStatements());
        block.statements().add(addReturnStatements());
        return block;
    }

    private Statement addTypeAsStatements() {
        String udtTypeFullName = udtGenCtx.getUdt().getGeneratedEntityClassInfo().getClassFullName();
        var frag = ast.newVariableDeclarationFragment();
        var castExpression = ast.newCastExpression();
        castExpression.setType(ast.newSimpleType(ast.newName(udtTypeFullName)));
        castExpression.setExpression(ast.newSimpleName("data"));
        frag.setInitializer(castExpression);
        frag.setName(ast.newSimpleName(tempData));
        var statement = ast.newVariableDeclarationStatement(frag);
        statement.setType(ast.newSimpleType(ast.newName(udtTypeFullName)));
        return statement;
    }

    private Statement addIfNullStatements() {

        var ifStatement = ast.newIfStatement();
        InfixExpression condition = ast.newInfixExpression();
        condition.setLeftOperand(ExpressionUtils.getMethodInvocation(ast, tempData, "get" + propertyName));
        condition.setOperator(InfixExpression.Operator.EQUALS);
        condition.setRightOperand(ast.newNullLiteral());
        ifStatement.setExpression(condition);

        var thenBlock = ast.newBlock();
        thenBlock.statements().add(ExpressionUtils.getReturnNullStatement(ast));
        ifStatement.setThenStatement(thenBlock);

        return ifStatement;
    }

    private ReturnStatement addReturnStatements() {
        var invocation = ExpressionUtils.getMethodInvocation(ast, tempData, "get"+propertyName);
        invocation = ExpressionUtils.getMethodInvocation(ast, invocation, "get"+propertyName);
        var returnStatement = ast.newReturnStatement();
        returnStatement.setExpression(invocation);
        return returnStatement;
    }
}
